using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using C4F.DevKit.Contacts;
using C4F.DevKit.Contacts.Components;
using C4F.DevKit.Contacts.Controls;

namespace C4F.DevKit.Contacts.Controls
{
    /// <summary>
    /// This control displays the list of contacts.
    /// </summary>
    [ToolboxItem(true), ToolboxBitmap(typeof(ContactsListView))]
    public partial class ContactsListView : UserControl
	{
        /// <summary>
        /// Represents the method run when a contact is double clicked in the list.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
		public delegate void ContactDoubleClickEventHandler(object sender, ContactDoubleClickArgs e);
		
        /// <summary>
        /// This is the event raised when a contact is double clicked in the list.
        /// </summary>
        public event ContactDoubleClickEventHandler ContactDoubleClick;

        #region Private Data
        
        private ContactSearch _contactsSearch = null;

        #endregion Private Data
        
        #region Constants

        private const string CONTACTID_COLUMN_SOURCE = "ContactID";
        private const string PIC_COLUMN_SOURCE = "ThumbnailPic";
		private const string NAME_COLUMN_SOURCE = "FormattedName";
        private const string EMAIL_COLUMN_SOURCE = "PersonalEmail1";
		private const string BUSINESSPHONE_COLUMN_SOURCE = "BusinessPhone";
		private const string NOTES_COLUMN_SOURCE = "Notes";

		private const int CONTACTID_COLUMN_INDEX = 0;
        private const int PIC_COLUMN_INDEX = 1;
		private const int NAME_COLUMN_INDEX = 2;
		private const int EMAIL_COLUMN_INDEX = 3;
		private const int BUSINESSPHONE_COLUMN_INDEX = 4;
		private const int NOTES_COLUMN_INDEX = 5;
        
        private const string CONTACT_EXPORTED_STATUS_SUCCESS_TEXT = "The contact was exported.";
        private const string CONTACT_EXPORTED_STATUS_FAILED_TEXT = "The contact was not exported.";
        private const string VCARD_FILE_NAME = "MyContact.vcf";

		#endregion Constants

		#region Constructors

        /// <summary>
        /// Initializes the control.
        /// </summary>
		public ContactsListView()
		{
			InitializeComponent();
            InitializeProperties();
		}

		#endregion Constructors

		#region Public Properties

        /// <summary>
        /// The ContactsService component to be used when performing actions on contacts.
        /// </summary>
        [Category("Contacts")]
        public ContactsService ContactsService { get; set; }

        /// <summary>
        /// The ContactSearch control to be used when searching.
        /// </summary>
        /// <remarks>The ContactsListView control listens for events on ContactsSearch to perform the actual search.</remarks>
		[Category("Contacts")]
		public ContactSearch ContactsSearch
		{
			get
			{
				return _contactsSearch;
			}
			set
			{
				_contactsSearch = value;

                if (_contactsSearch != null)
                    _contactsSearch.ContactsSearch += new ContactSearch.ContactsSearchEventHandler(SearchContacts);
			}
		}
        
        /// <summary>
        /// Returns the id of the contact that is currently selected.
        /// </summary>
		[Browsable(false)]
		public string SelectedContactID
		{
			get
			{
				if (dgContactList.SelectedRows[0].Cells[CONTACTID_COLUMN_INDEX].Value == null)
					return string.Empty;
				else
					return dgContactList.SelectedRows[0].Cells[CONTACTID_COLUMN_INDEX].Value.ToString();
			}
		}

		#endregion Public Properties

		#region Methods

		#region Event Handlers

		private void ContactsListView_Load(object sender, EventArgs e)
		{
            try
            {
                if (!this.DesignMode)
                {
                    if (ContactsService != null)
                    {
                        RefreshList();
                    }
                }
            }
            catch (Exception ex)
            {
                DisplayException(ex);
            }
		}

		private void dgContactList_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
		{
            try
            {
                OnContactDoubleClick(dgContactList.Rows[e.RowIndex].Cells[CONTACTID_COLUMN_INDEX].Value.ToString());
            }
            catch (Exception ex)
            {
                DisplayException(ex);
            }
		}

        private void mnuRemoveContact_Click(object sender, EventArgs e)
        {
            try
            {
                OnRemoveContact();
            }
            catch (Exception ex)
            {
                DisplayException(ex);
            }
        }

        private void mnuExportToVCard_Click(object sender, EventArgs e)
        {
            try
            {
                OnExportToVCard();
            }
            catch (Exception ex)
            {
                DisplayException(ex);
            }
        }

        private void mnuExportToDatabase_Click(object sender, EventArgs e)
        {
            try
            {
                OnExportToDB();
            }
            catch (Exception ex)
            {
                DisplayException(ex);
            }
        }        

		#endregion Event Handlers

		#region Private

		private void ConfigureColumnBindings()
		{
			dgContactList.Columns[CONTACTID_COLUMN_INDEX].DataPropertyName = CONTACTID_COLUMN_SOURCE;
            dgContactList.Columns[PIC_COLUMN_INDEX].DataPropertyName = PIC_COLUMN_SOURCE;
			dgContactList.Columns[NAME_COLUMN_INDEX].DataPropertyName = NAME_COLUMN_SOURCE;
			dgContactList.Columns[EMAIL_COLUMN_INDEX].DataPropertyName = EMAIL_COLUMN_SOURCE;
			dgContactList.Columns[BUSINESSPHONE_COLUMN_INDEX].DataPropertyName = BUSINESSPHONE_COLUMN_SOURCE;
			dgContactList.Columns[NOTES_COLUMN_INDEX].DataPropertyName = NOTES_COLUMN_SOURCE;
		}

        private void OnContactDoubleClick(string contactID)
        {
            if (ContactDoubleClick != null)
            {
                ContactDoubleClickArgs args = new ContactDoubleClickArgs();
                args.ContactID = contactID;
                ContactDoubleClick(this, args);
            }
        }

        private void SearchContacts(object sender, ContactsSearchEventArgs e)
        {
            try
            {
                ContactsSearchFilter filter = e.Filter;
                RefreshList(ContactsService.SearchSimpleContacts(filter.FirstName, filter.LastName, filter.StreetAddress, filter.City, filter.State, filter.Country));
            }
            catch (Exception ex)
            {
                DisplayException(ex);
            }
        }

        private void OnRemoveContact()
        {
            if (MessageBox.Show("Are you sure you want to remove this contact?", "Remove Contact?", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) == DialogResult.Yes)
            {
                if (SelectedContactID != string.Empty)
                {
                    ContactsService.RemoveContact(SelectedContactID);
                    RefreshList();
                }
            }
        }

        private void OnExportToVCard()
        {
            if (!string.IsNullOrEmpty(SelectedContactID))
            {
                string filePath = string.Format("{0}\\{1}", Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory), VCARD_FILE_NAME);
                if (ContactsService.ExportContactToVCard(SelectedContactID, filePath))
                    MessageBox.Show(string.Format("{0}. File path: {1}", CONTACT_EXPORTED_STATUS_SUCCESS_TEXT, filePath), "Contact Exported", MessageBoxButtons.OK, MessageBoxIcon.Information);
                else
                    MessageBox.Show(CONTACT_EXPORTED_STATUS_FAILED_TEXT, "Contact Exported", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            else
            {
                MessageBox.Show("Please select a contact.");
            }
        }

        private void DisplayException(Exception ex)
        {
            if (ex != null)
                MessageBox.Show(ex.ToString());
        }
        
        private void InitializeProperties()
        {
            ContactsService = null;
            ContactsSearch = null;
        }

        private void OnExportToDB()
        {            
            ContactsService.ExportContactToDatabase(SelectedContactID);
            MessageBox.Show(CONTACT_EXPORTED_STATUS_SUCCESS_TEXT, "Contact Exported", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }

		#endregion Private

		#region Public 

        /// <summary>
        /// Refreshes the list with the specified contacts.
        /// </summary>
        /// <param name="simpleContacts"></param>
        /// <remarks>If the specified contacts collection is null, they will be retrieved.</remarks>
		public void RefreshList(IEnumerable<SimpleContactView> simpleContacts)
		{
            try
            {
                if (simpleContacts == null)
                    bindingSource1.DataSource = ContactsService.GetAllSimpleContacts();
                else
                    bindingSource1.DataSource = simpleContacts;

                ConfigureColumnBindings();
            }
            catch (Exception ex)
            {
                DisplayException(ex);
            }
		}

        /// <summary>
        /// Refreshes the list by retrieving the contacts from it data source.
        /// </summary>
        public void RefreshList()
        {
            try
            {
                RefreshList(null);
            }
            catch (Exception ex)
            {
                DisplayException(ex);
            }
        }

		#endregion Public
               
		#endregion Methods
              
	}
}